package hook

import (
	"net/http"
	"strings"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"ICan/errmsg"
)

func Middle(ctx *gin.Context) {
	ctx.Header("Access-Control-Allow-Origin", "*")
	ctx.Next()
}

var JwtKey = []byte("qwerty")

type MyClaims struct {
	Username string `json:"username"`
	jwt.StandardClaims
}
var expireTime int64
//生成token
func SetToken(username string) (string, int) {
	expireTime = time.Now().Add(8 * time.Hour).Unix()
	SetClaims := MyClaims {
		username,
		jwt.StandardClaims{
			ExpiresAt:expireTime,
			Issuer:"ginblog",
		},
	}
	reqClaim := jwt.NewWithClaims(jwt.SigningMethodHS256,SetClaims)
	token, err := reqClaim.SignedString(JwtKey)
	if err != nil {
		return "", errmsg.Error
	}
	return token, errmsg.Succse
}
//验证token
func CheckToken(token string)(*MyClaims, int){
	settoken, _ := jwt.ParseWithClaims(token, &MyClaims{}, func(token *jwt.Token) (interface{}, error){
		return JwtKey, nil
	})
	if key, _ := settoken.Claims.(*MyClaims); settoken.Valid {
		return key, errmsg.Succse
	}else {
		return nil, errmsg.Error
	}
}
//jwt中间件

func JwtToken() gin.HandlerFunc {
	return func (c *gin.Context){
		tokenHeader := c.Request.Header.Get("Authorization")
		code := errmsg.Succse
		if tokenHeader == "" {
			code = errmsg.Error_token_no
			c.JSON(http.StatusOK,gin.H{
				"code":code,
				"msg":errmsg.GetErrMSg(code),
			})
			c.Abort()
			return
		}
		checkToken := strings.SplitN(tokenHeader, " ", 2)
		if len(checkToken) != 2 && checkToken[0] != "Bearer" {
			code = errmsg.Error_token_no
			c.JSON(http.StatusOK,gin.H{
				"code":code,
				"msg":errmsg.GetErrMSg(code),
			})
			c.Abort()
			return
		}
		key, Tcode := CheckToken(checkToken[1])
		if time.Now().Unix() > expireTime {
			token, _ := SetToken("x")
			code = errmsg.Error_token_time
			c.JSON(http.StatusOK,gin.H{
				"code":code,
				"msg":errmsg.GetErrMSg(code),
				"token":token,
			})
			c.Abort()
			return
		}
		if Tcode == 404 {
			code = errmsg.Error_token_no
			c.JSON(http.StatusOK,gin.H{
				"code":code,
				"msg":errmsg.GetErrMSg(code),
			})
			c.Abort()
			return
		}
		c.Set("username",key.Username)
		c.Next()
	}
}